package com.mtr.middleware;

import com.mtr.sdk.ExecuteResult;
import com.mtr.sdk.IMiddleware;
import com.mtr.sdk.Parameter;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

public class PythonRuntime  implements IMiddleware {
    @Override
    public ExecuteResult Execute(List<Parameter> parameters) {

        //dburl,uid,pwd,sql
        var parameterMaps = new HashMap<String, String>();
        for (var p : parameters) {
            parameterMaps.put(p.getName(), p.getValue());
        }

        if(!parameterMaps.containsKey("command")||!parameterMaps.containsKey("params"))
            return  null;


        String exe = "python";
        String commandContent = parameterMaps.get("command");

        String command = getCommandPath(commandContent);

        String[] params =  parameterMaps.get("params").split(",");


        List<String> cmdArr = new ArrayList<>() ;

        cmdArr.add(exe);
        cmdArr.add(command);

        for(var param:params)
        {
            cmdArr.add(URLEncoder.encode(param,Charset.forName("utf-8")));
        }
        String result = execute(cmdArr.toArray(new String[]{}));
        result = URLDecoder.decode(result,Charset.forName("utf-8"));
        //new File(command).delete();
        return new ExecuteResult(result);
    }

    /**
     * 获取命令路径（python文件路径）
     * @param commandContent
     * @return
     */
    private String getCommandPath(String commandContent)  {
        String path = new File("admin-web/target/pythonruntime").getAbsolutePath() ;

        File dir = new File(path);
        //已存在先清空
        if (!dir.exists()) dir.mkdirs();

        String filename=UUID.randomUUID().toString();

        try {
            filename=getMD5(commandContent.getBytes());
        } catch (NoSuchAlgorithmException | IOException e) {
            e.printStackTrace();
        }

        String filePath = path+"/"+ filename+".py";

        File file = new File(filePath);

        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        //if (file.exists()) file.delete();

        OutputStream os = null;
        try {
            os = new FileOutputStream(file);
            os.write(commandContent.getBytes(Charset.forName("utf-8")));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  filePath;
    }

    /**
     * 执行
     * @param cmdArr
     * @return
     */
    private String execute(String[] cmdArr)
    {
        try{
            Process process = Runtime.getRuntime().exec(cmdArr);
            InputStream is = process.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            byte[] data= dis.readAllBytes();
            String str = new String(data, "utf-8");
            process.waitFor();
            //去掉尾部的回车
            if(str!=null&&str.length()>2)
                str = str.substring(0,str.length()-2);
            return str;
        }catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getMD5(byte[] content) throws NoSuchAlgorithmException, IOException {
        StringBuffer md5 = new StringBuffer();
        MessageDigest md = MessageDigest.getInstance("MD5");

        md.update(content, 0, content.length);
        byte[] mdbytes = md.digest();

        // convert the byte to hex format
        for (int i = 0; i < mdbytes.length; i++) {
            md5.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
        }
        return md5.toString();
    }
}
